/**
  ******************************************************************************
  * @file    tc32l010_pca.c
  * @author  CHIPAT Application Team
  * @brief   PCA HAL module driver
  *          This file provides firmware functions to manage the following
  *          functionalities of the PCA peripheral:
  *           + Pca Initialization
  *           + Pca Start
  *           + Pca Start Interruption
  @verbatim
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "tc32l010_pca.h"

/** @addtogroup tc32l010_Driver
  * @{
  */

/** @defgroup PCA PCA
  * @brief PCA HAL module driver
  * @{
  */


/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/
/** @defgroup PCA_Private_Functions PCA Private Functions
  * @{
  */

/**
  * @}
  */

/* Exported functions ---------------------------------------------------------*/

/**
  * @brief  Initializes the PCA Unit basic function according to the specified parameters
	*					in the PCA_TypeDef and create the associated handle.
  * @note no comment
  * @param  PCA_BaseInitStruct : PCA_TypeDef
  * @retval HAL status
  */
void PCA_BaseInit(PCA_TypeDef* PCAx, PCA_BaseInitTypeDef* PCA_BaseInitStruct)
{
    uint32_t mode;

    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));
    assert_param(IS_PCA_CIDL_MODE(PCA_BaseInitStruct->RunInIdleMode));
    assert_param(IS_PCA_CLK_SEL(PCA_BaseInitStruct->ClkSrcSel));

    /* Initialize the PCA */
    mode = PCAx->MOD;
    mode &= ~(PCA_MOD_CIDL|PCA_MOD_CPS|PCA_MOD_CFIE);

    PCAx->MOD = mode | PCA_BaseInitStruct->RunInIdleMode | PCA_BaseInitStruct->ClkSrcSel;

    PCAx->CARR = PCA_BaseInitStruct->Period;
}


/**
  * @brief  DeInitializes the PCA peripheral
  * @param  PCAx : PCA_TypeDef
  * @retval HAL status
  */
void PCA_BaseDeInit(PCA_TypeDef* PCAx)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    PCAx->CR &= ~PCA_CR_CR;
    PCAx->MOD &= ~(PCA_MOD_CFIE | PCA_MOD_CPS | PCA_MOD_CIDL);
}


/**
  * @brief  Starts the PCA generation.
  * @param  PCAx : PCA PCA_TypeDef
  * @retval HAL status
*/
void PCA_Start(PCA_TypeDef* PCAx)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    /* Start the pca*/
    PCAx->CR |= PCA_CR_CR;
}


/**
  * @brief  Stops the PCA generation.
  * @param  PCAx : PCA PCA_TypeDef
  * @retval HAL status
*/
void PCA_Stop(PCA_TypeDef* PCAx)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    /* Stop pca */
    PCAx->CR &= ~PCA_CR_CR;
}


/**
  * @brief  Starts the PCA generation in interrupt mode.
  * @param  hpca : PCA_TypeDef
  * @param  interrupt: specifies the PCA interrupt source to enable.
  *          This parameter can be one of the following values:
  *            @arg PCA_IT_CC0: Capture/Compare 0 interrupt
  *            @arg PCA_IT_CC1: Capture/Compare 1 interrupt
  *            @arg PCA_IT_CC2: Capture/Compare 2 interrupt
  *            @arg PCA_IT_CC3: Capture/Compare 3 interrupt
  *            @arg PCA_IT_CC4: Capture/Compare 4 interrupt
  *            @arg PCA_IT_OVERFLOW: Overflow interrupt
  * @retval HAL status
*/
void PCA_Start_IT(PCA_TypeDef* PCAx, uint32_t intid)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    /* Enable the PCA interrupt */
    if((intid & PCA_IT_CC0) == PCA_IT_CC0)
    {
        PCAx->CCAPM0 |= PCA_CCAPMx_CCIE;
    }

    if((intid & PCA_IT_CC1) == PCA_IT_CC1)
    {
        PCAx->CCAPM1 |= PCA_CCAPMx_CCIE;
    }

    if((intid & PCA_IT_CC2) == PCA_IT_CC2)
    {
        PCAx->CCAPM2 |= PCA_CCAPMx_CCIE;
    }

    if((intid & PCA_IT_CC3) == PCA_IT_CC3)
    {
        PCAx->CCAPM3 |= PCA_CCAPMx_CCIE;
    }

    if((intid & PCA_IT_CC4) == PCA_IT_CC4)
    {
        PCAx->CCAPM4 |= PCA_CCAPMx_CCIE;
    }

    if((intid & PCA_IT_OVERFLOW) == PCA_IT_OVERFLOW)
    {
        PCAx->MOD |= PCA_MOD_CFIE;
    }

    /* start the Peripheral */
    PCAx->CR |= PCA_CR_CR;
}


/**
  * @brief  Stops the PCA generation in interrupt mode.
  * @param  hpca : PCA_TypeDef
  * @param  interrupt: specifies the PCA interrupt source to enable.
  *          This parameter can be one of the following values:
  *            @arg PCA_IT_CC0: Capture/Compare 0 interrupt
  *            @arg PCA_IT_CC1: Capture/Compare 1 interrupt
  *            @arg PCA_IT_CC2: Capture/Compare 2 interrupt
  *            @arg PCA_IT_CC3: Capture/Compare 3 interrupt
  *            @arg PCA_IT_CC4: Capture/Compare 4 interrupt
  *            @arg PCA_IT_OVERFLOW: Overflow interrupt
  * @retval HAL status
*/
void PCA_Stop_IT(PCA_TypeDef* PCAx, uint32_t intid)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    /* Disable the PCA interrupt */
    if((intid & PCA_IT_CC0) == PCA_IT_CC0)
    {
        PCAx->CCAPM0 &= ~PCA_CCAPMx_CCIE;
    }

    if((intid & PCA_IT_CC1) == PCA_IT_CC1)
    {
        PCAx->CCAPM1 &= ~PCA_CCAPMx_CCIE;
    }

    if((intid & PCA_IT_CC2) == PCA_IT_CC2)
    {
        PCAx->CCAPM2 &= ~PCA_CCAPMx_CCIE;
    }

    if((intid & PCA_IT_CC3) == PCA_IT_CC3)
    {
        PCAx->CCAPM3 &= ~PCA_CCAPMx_CCIE;
    }

    if((intid & PCA_IT_CC4) == PCA_IT_CC4)
    {
        PCAx->CCAPM4 &= ~PCA_CCAPMx_CCIE;
    }

    if((intid & PCA_IT_OVERFLOW) == PCA_IT_OVERFLOW)
    {
        PCAx->MOD &= ~PCA_MOD_CFIE;
    }

    /* Stop pca */
    PCAx->CR &= ~PCA_CR_CR;
}


/**
  * @brief  Starts the PCA output compare generation.
  * @param  hpca : PCA_TypeDef
  * @param  __CHANNEL__ : PCA Channel associated with the capture compare register
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: Capture/Compare channel0
  *            @arg PCA_CHANNEL_1: Capture/Compare channel1
  *            @arg PCA_CHANNEL_2: Capture/Compare channel2
  *            @arg PCA_CHANNEL_3: Capture/Compare channel3
  *            @arg PCA_CHANNEL_4: Capture/Compare channel4
  * @retval HAL status
*/
void PCA_OC_Start(PCA_TypeDef* PCAx, uint32_t Channel)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    if (Channel & PCA_CHANNEL_0)
    {
        PCAx->POCR |= PCA_POCR_POE0;
    }

    if (Channel & PCA_CHANNEL_1)
    {
        PCAx->POCR |= PCA_POCR_POE1;
    }

    if (Channel & PCA_CHANNEL_2)
    {
        PCAx->POCR |= PCA_POCR_POE2;
    }

    if (Channel & PCA_CHANNEL_3)
    {
        PCAx->POCR |= PCA_POCR_POE3;
    }

    if (Channel & PCA_CHANNEL_4)
    {
        PCAx->POCR |= PCA_POCR_POE4;
    }

    /* Start the pca*/
    PCAx->CR |= PCA_CR_CR;
}


/**
  * @brief  Stops the PCA output compare generation.
  * @param  hpca : PCA_TypeDef
  * @param  __CHANNEL__ : PCA Channel associated with the capture compare register
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: Capture/Compare channel0
  *            @arg PCA_CHANNEL_1: Capture/Compare channel1
  *            @arg PCA_CHANNEL_2: Capture/Compare channel2
  *            @arg PCA_CHANNEL_3: Capture/Compare channel3
  *            @arg PCA_CHANNEL_4: Capture/Compare channel4
  * @retval HAL status
*/
void PCA_OC_Stop(PCA_TypeDef* PCAx, uint32_t Channel)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    if (Channel & PCA_CHANNEL_0)
    {
        PCAx->POCR &= ~PCA_POCR_POE0;
    }

    if (Channel & PCA_CHANNEL_1)
    {
        PCAx->POCR &= ~PCA_POCR_POE1;
    }

    if (Channel & PCA_CHANNEL_2)
    {
        PCAx->POCR &= ~PCA_POCR_POE2;
    }

    if (Channel & PCA_CHANNEL_3)
    {
        PCAx->POCR &= ~PCA_POCR_POE3;
    }

    if (Channel & PCA_CHANNEL_4)
    {
        PCAx->POCR &= ~PCA_POCR_POE4;
    }

    /* Stop the pca*/
    PCAx->CR &= ~PCA_CR_CR;
}


/**
  * @brief  Starts the PCA output compare generation and enable interrupt.
  * @param  hpca : PCA_TypeDef
  * @param  __CHANNEL__ : PCA Channel associated with the capture compare register
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: Capture/Compare channel0
  *            @arg PCA_CHANNEL_1: Capture/Compare channel1
  *            @arg PCA_CHANNEL_2: Capture/Compare channel2
  *            @arg PCA_CHANNEL_3: Capture/Compare channel3
  *            @arg PCA_CHANNEL_4: Capture/Compare channel4
  * @retval HAL status
*/
void PCA_OC_Start_IT(PCA_TypeDef* PCAx, uint32_t Channel)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    if (Channel & PCA_CHANNEL_0)
    {
        PCAx->POCR |= PCA_POCR_POE0;
        PCAx->CCAPM0 |= PCA_CCAPMx_CCIE;
    }

    if (Channel & PCA_CHANNEL_1)
    {
        PCAx->POCR |= PCA_POCR_POE1;
        PCAx->CCAPM1 |= PCA_CCAPMx_CCIE;
    }

    if (Channel & PCA_CHANNEL_2)
    {
        PCAx->POCR |= PCA_POCR_POE2;
        PCAx->CCAPM2 |= PCA_CCAPMx_CCIE;
    }

    if (Channel & PCA_CHANNEL_3)
    {
        PCAx->POCR |= PCA_POCR_POE3;
        PCAx->CCAPM3 |= PCA_CCAPMx_CCIE;
    }

    if (Channel & PCA_CHANNEL_4)
    {
        PCAx->POCR |= PCA_POCR_POE4;
        PCAx->CCAPM4 |= PCA_CCAPMx_CCIE;
    }

    /* Start the pca*/
    PCAx->CR |= PCA_CR_CR;
}


/**
  * @brief  Stops the PCA output compare generation and disable interrupt.
  * @param  hpca : PCA_TypeDef
  * @param  __CHANNEL__ : PCA Channel associated with the capture compare register
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: Capture/Compare channel0
  *            @arg PCA_CHANNEL_1: Capture/Compare channel1
  *            @arg PCA_CHANNEL_2: Capture/Compare channel2
  *            @arg PCA_CHANNEL_3: Capture/Compare channel3
  *            @arg PCA_CHANNEL_4: Capture/Compare channel4
  * @retval HAL status
*/
void PCA_OC_Stop_IT(PCA_TypeDef* PCAx, uint32_t Channel)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    if (Channel & PCA_CHANNEL_0)
    {
        PCAx->POCR &= ~PCA_POCR_POE0;
        PCAx->CCAPM0 &= ~PCA_CCAPMx_CCIE;
    }

    if (Channel & PCA_CHANNEL_1)
    {
        PCAx->POCR &= ~PCA_POCR_POE1;
        PCAx->CCAPM1 &= ~PCA_CCAPMx_CCIE;
    }

    if (Channel & PCA_CHANNEL_2)
    {
        PCAx->POCR &= ~PCA_POCR_POE2;
        PCAx->CCAPM2 &= ~PCA_CCAPMx_CCIE;
    }

    if (Channel & PCA_CHANNEL_3)
    {
        PCAx->POCR &= ~PCA_POCR_POE3;
        PCAx->CCAPM3 &= ~PCA_CCAPMx_CCIE;
    }

    if (Channel & PCA_CHANNEL_4)
    {
        PCAx->POCR &= ~PCA_POCR_POE4;
        PCAx->CCAPM4 &= ~PCA_CCAPMx_CCIE;
    }

    /* Stop the pca*/
    PCAx->CR &= ~PCA_CR_CR;
}

/**
  * @brief  Initializes the PCA Input Capture Channels according to the specified
  *         parameters in the PCA_IC_InitTypeDef.
  * @param  hpca : PCA IC handle
  * @param  sConfig : PCA Input Capture configuration structure
  *          This parameter can be one of the following values:
  *            @arg PCA_INPUT_POLARITY_NONE
  *            @arg PCA_INPUT_POLARITY_FALLING
  *            @arg PCA_INPUT_POLARITY_RISING
  *            @arg PCA_INPUT_POLARITY_BOTH
  * @param  Channel : PCA Channels to be enabled
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: PCA Channel 0 selected
  *            @arg PCA_CHANNEL_1: PCA Channel 1 selected
  *            @arg PCA_CHANNEL_2: PCA Channel 2 selected
  *            @arg PCA_CHANNEL_3: PCA Channel 3 selected
  *            @arg PCA_CHANNEL_4: PCA Channel 4 selected
  * @retval HAL status
  */
void PCA_IC_ConfigChannel(PCA_TypeDef* PCAx, PCA_ICInitTypeDef* sConfig, uint32_t Channel)
{
    uint32_t reg;

    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    if (Channel == PCA_CHANNEL_0)
    {
        /* TI0 Channel0 input capture configuration */
        reg = PCAx->CCAPM0;
        reg &= ~(PCA_CCAPMx_CAPP | PCA_CCAPMx_CAPN);
        PCAx->CCAPM0 = reg | sConfig->ICPolarity;
    }
    if (Channel == PCA_CHANNEL_1)
    {
        /* TI1 Channel1 input capture configuration */
        reg = PCAx->CCAPM1;
        reg &= ~(PCA_CCAPMx_CAPP | PCA_CCAPMx_CAPN);
        PCAx->CCAPM1 = reg | sConfig->ICPolarity;
    }
    if (Channel == PCA_CHANNEL_2)
    {
        /* TI2 Channel2 input capture configuration */
        reg = PCAx->CCAPM2;
        reg &= ~(PCA_CCAPMx_CAPP | PCA_CCAPMx_CAPN);
        PCAx->CCAPM2 = reg | sConfig->ICPolarity;
    }
    if (Channel == PCA_CHANNEL_3)
    {
        /* TI3 Channel3 input capture configuration */
        reg = PCAx->CCAPM3;
        reg &= ~(PCA_CCAPMx_CAPP | PCA_CCAPMx_CAPN);
        PCAx->CCAPM3 = reg | sConfig->ICPolarity;
    }
    if (Channel == PCA_CHANNEL_4)
    {
        /* TI4 Channel4 input capture configuration */
        reg = PCAx->CCAPM4;
        reg &= ~(PCA_CCAPMx_CAPP | PCA_CCAPMx_CAPN);
        PCAx->CCAPM4 = reg | sConfig->ICPolarity;
    }
}


/**
  * @brief  Initializes the PCA output compare Channels according to the specified
  *         parameters in the PCA_OC_InitTypeDef.
  * @param  hpca : PCA_TypeDef
  * @param  sConfig : PCA output compare configuration structure
  * @param  Channel : PCA Channels to be enabled
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: PCA Channel 0 selected
  *            @arg PCA_CHANNEL_1: PCA Channel 1 selected
  *            @arg PCA_CHANNEL_2: PCA Channel 2 selected
  *            @arg PCA_CHANNEL_3: PCA Channel 3 selected
  *            @arg PCA_CHANNEL_4: PCA Channel 4 selected
  * @retval HAL status
  */
void PCA_OC_ConfigChannel(PCA_TypeDef* PCAx, PCA_OCInitTypeDef* sConfig, uint32_t Channel)
{
    uint32_t reg;

    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    if (Channel == PCA_CHANNEL_0)
    {
        /* PCA Channel0 input capture configuration */
        reg = PCAx->CCAPM0;
        reg &= ~(PCA_CCAPMx_ECOM | PCA_CCAPMx_MAT | PCA_CCAPMx_TOG | PCA_CCAPMx_PWM | PCA_CCAPMx_EPWM);
        PCAx->CCAPM0 = reg | sConfig->CompareEnable | sConfig->MatEnable | sConfig->TogEnable | sConfig->PwmEnable | sConfig->b16PwmEnable;

        /* Setting period */
        PCAx->CCAP0 = sConfig->Period;
    }
    if (Channel == PCA_CHANNEL_1)
    {
        /*PCA Channel1 input capture configuration */
        reg = PCAx->CCAPM1;
        reg &= ~(PCA_CCAPMx_ECOM | PCA_CCAPMx_MAT | PCA_CCAPMx_TOG | PCA_CCAPMx_PWM | PCA_CCAPMx_EPWM);
        PCAx->CCAPM1 = reg | sConfig->CompareEnable | sConfig->MatEnable | sConfig->TogEnable | sConfig->PwmEnable | sConfig->b16PwmEnable;

        /* Setting period */
        PCAx->CCAP1 = sConfig->Period;
    }
    if (Channel == PCA_CHANNEL_2)
    {
        /* TI2 Channel2 input capture configuration */
        reg = PCAx->CCAPM2;
        reg &= ~(PCA_CCAPMx_ECOM | PCA_CCAPMx_MAT | PCA_CCAPMx_TOG | PCA_CCAPMx_PWM | PCA_CCAPMx_EPWM);
        PCAx->CCAPM2 = reg | sConfig->CompareEnable | sConfig->MatEnable | sConfig->TogEnable | sConfig->PwmEnable | sConfig->b16PwmEnable;
        /* Setting period */
        PCAx->CCAP2 = sConfig->Period;
    }
    if (Channel == PCA_CHANNEL_3)
    {
        /* TI3 Channel3 input capture configuration */
        reg = PCAx->CCAPM3;
        reg &= ~(PCA_CCAPMx_ECOM | PCA_CCAPMx_MAT | PCA_CCAPMx_TOG | PCA_CCAPMx_PWM | PCA_CCAPMx_EPWM);
        PCAx->CCAPM3 = reg | sConfig->CompareEnable | sConfig->MatEnable | sConfig->TogEnable | sConfig->PwmEnable | sConfig->b16PwmEnable;

        /* Setting period */
        PCAx->CCAP3 = sConfig->Period;
    }
    if (Channel == PCA_CHANNEL_4)
    {
        /* TI4 Channel4 input capture configuration */
        reg = PCAx->CCAPM4;
        reg &= ~(PCA_CCAPMx_ECOM | PCA_CCAPMx_MAT | PCA_CCAPMx_TOG | PCA_CCAPMx_PWM | PCA_CCAPMx_EPWM);
        PCAx->CCAPM4 = reg | sConfig->CompareEnable | sConfig->MatEnable | sConfig->TogEnable | sConfig->PwmEnable | sConfig->b16PwmEnable;

        /* Setting period */
        PCAx->CCAP4 = sConfig->Period;
    }
}

/**
  * @brief  Set the PCA output compare Channels Polarity Inversion.
  * @param  hpca : PCA_TypeDef
  * @param  sConfig : PCA output compare configuration structure
  * @param  Channel : PCA Channels to be enabled
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: PCA Channel 0 selected
  *            @arg PCA_CHANNEL_1: PCA Channel 1 selected
  *            @arg PCA_CHANNEL_2: PCA Channel 2 selected
  *            @arg PCA_CHANNEL_3: PCA Channel 3 selected
  *            @arg PCA_CHANNEL_4: PCA Channel 4 selected
  * @param  NewState: new state of the DMA Request sources.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void PCA_OC_PolarityInversionCmd(PCA_TypeDef* PCAx, uint32_t Channel, FunctionalState NewState)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));
    assert_param(IS_FUNCTIONAL_STATE(NewState));

    if (NewState != DISABLE)
    {
        PCAx->POCR |= Channel << 8;
    }
    else
    {
        PCAx->POCR &= ~(Channel << 8);
    }
}

/**
  * @brief  Sets the PCAx Autoreload Register value
  * @param  PCAx: select the PCA peripheral.
  * @param  Autoreload: specifies the Autoreload register new value.
  * @retval None
  */
void PCA_SetAutoreload(PCA_TypeDef* PCAx, uint16_t Autoreload)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    /* Set the Autoreload Register value */
    PCAx->CARR = Autoreload;
}

/**
  * @brief  Set the specified PCA count value.
  * @param  PCAx: select the PCA peripheral.
  * @param  cnt: cnt vaule should be 0~0xFFFF.
  * @retval None.
  */
void PCA_SetCounter(PCA_TypeDef* PCAx, uint16_t cnt)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    if((PCAx->CR & PCA_CR_CR) != RESET)
    {
        PCAx->CR &= ~PCA_CR_CR;
        PCAx->CNT = cnt;
        PCAx->CR |= PCA_CR_CR;
    }
    else
    {
        PCAx->CNT = cnt;
    }
}

/**
  * @brief  Get the specified PCA count value.
  * @param  PCAx: select the PCA peripheral.
  * @retval The count value.
  */
uint16_t PCA_GetCounter(PCA_TypeDef* PCAx)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    return (PCAx->CNT);
}

/**
  * @brief  Get the specified PCA CCAP Out flag.
  * @param  PCAx: select the PCA peripheral.
  * @param  Channel: PCA Channels to be enabled
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: PCA Channel 0 selected
  *            @arg PCA_CHANNEL_1: PCA Channel 1 selected
  *            @arg PCA_CHANNEL_2: PCA Channel 2 selected
  *            @arg PCA_CHANNEL_3: PCA Channel 3 selected
  *            @arg PCA_CHANNEL_4: PCA Channel 4 selected
  * @retval The new state of PCA_FLAG (SET or RESET).
  */
FlagStatus PCA_GetOut(PCA_TypeDef* PCAx, uint32_t Channel)
{
    FlagStatus bitstatus = RESET;

    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));

    if((PCAx->CCAPO & Channel) != RESET)
    {
        bitstatus = SET;
    }
    else
    {
        bitstatus = RESET;
    }

    return bitstatus;
}

/**
  * @brief  Set the specified PCA CCAP value.
  * @param  PCAx: select the PCA peripheral.
  * @param  Channel: PCA Channels to be enabled
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: PCA Channel 0 selected
  *            @arg PCA_CHANNEL_1: PCA Channel 1 selected
  *            @arg PCA_CHANNEL_2: PCA Channel 2 selected
  *            @arg PCA_CHANNEL_3: PCA Channel 3 selected
  *            @arg PCA_CHANNEL_4: PCA Channel 4 selected
  * @param  Value: PCA CCAP adress value.
  * @retval None.
  */
void PCA_SetCcap(PCA_TypeDef* PCAx, uint32_t Channel, uint16_t Value)
{
    switch(Channel)
    {
    case PCA_CHANNEL_0:
        PCAx->CCAP0 = Value;
        break;
    case PCA_CHANNEL_1:
        PCAx->CCAP1 = Value;
        break;
    case PCA_CHANNEL_2:
        PCAx->CCAP2 = Value;
        break;
    case PCA_CHANNEL_3:
        PCAx->CCAP3 = Value;
        break;
    case PCA_CHANNEL_4:
        PCAx->CCAP4 = Value;
        break;
    default:
        break;
    }
}

/**
  * @brief  Get the specified PCA CCAP value.
  * @param  PCAx: select the PCA peripheral.
  * @param  Channel: PCA Channels to be enabled
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: PCA Channel 0 selected
  *            @arg PCA_CHANNEL_1: PCA Channel 1 selected
  *            @arg PCA_CHANNEL_2: PCA Channel 2 selected
  *            @arg PCA_CHANNEL_3: PCA Channel 3 selected
  *            @arg PCA_CHANNEL_4: PCA Channel 4 selected
  * @retval CCAP value.
  */
uint16_t PCA_GetCcap(PCA_TypeDef* PCAx, uint32_t Channel)
{
    uint16_t tmp;

    switch(Channel)
    {
    case PCA_CHANNEL_0:
        tmp = PCAx->CCAP0;
        break;
    case PCA_CHANNEL_1:
        tmp = PCAx->CCAP1;
        break;
    case PCA_CHANNEL_2:
        tmp = PCAx->CCAP2;
        break;
    case PCA_CHANNEL_3:
        tmp = PCAx->CCAP3;
        break;
    case PCA_CHANNEL_4:
        tmp = PCAx->CCAP4;
        break;
    default:
        break;
    }

    return tmp;
}

/**
  * @brief  Set the specified PCA CCAP value.
  * @param  PCAx: select the PCA peripheral.
  * @param  Channel: PCA Channels to be enabled
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: PCA Channel 0 selected
  *            @arg PCA_CHANNEL_1: PCA Channel 1 selected
  *            @arg PCA_CHANNEL_2: PCA Channel 2 selected
  *            @arg PCA_CHANNEL_3: PCA Channel 3 selected
  *            @arg PCA_CHANNEL_4: PCA Channel 4 selected
  * @param  ValueH: PCA CCAP high adress value.
  * @param  ValueL: PCA CCAP low address value.
  * @retval None.
  */
void PCA_SetCcapHL(PCA_TypeDef* PCAx, uint32_t Channel, uint8_t ValueH, uint8_t ValueL)
{
    switch(Channel)
    {
    case PCA_CHANNEL_0:
        PCAx->CCAP0L = ValueL;
        PCAx->CCAP0H = ValueH;
        break;
    case PCA_CHANNEL_1:
        PCAx->CCAP1L = ValueL;
        PCAx->CCAP1H = ValueH;
        break;
    case PCA_CHANNEL_2:
        PCAx->CCAP2L = ValueL;
        PCAx->CCAP2H = ValueH;
        break;
    case PCA_CHANNEL_3:
        PCAx->CCAP3L = ValueL;
        PCAx->CCAP3H = ValueH;
        break;
    case PCA_CHANNEL_4:
        PCAx->CCAP4L = ValueL;
        PCAx->CCAP4H = ValueH;
        break;
    default:
        break;
    }
}

/**
  * @brief  Get the specified PCA CCAP value.
  * @param  PCAx: select the PCA peripheral.
  * @param  Channel: PCA Channels to be enabled
  *          This parameter can be one of the following values:
  *            @arg PCA_CHANNEL_0: PCA Channel 0 selected
  *            @arg PCA_CHANNEL_1: PCA Channel 1 selected
  *            @arg PCA_CHANNEL_2: PCA Channel 2 selected
  *            @arg PCA_CHANNEL_3: PCA Channel 3 selected
  *            @arg PCA_CHANNEL_4: PCA Channel 4 selected
  * @param  ValueH: point the PCA CCAP high adress value.
  * @param  ValueL: point the PCA CCAP low address value.
  * @retval None.
  */
void PCA_GetCcapHL(PCA_TypeDef* PCAx, uint32_t Channel, uint8_t* ValueH, uint8_t* ValueL)
{
    switch(Channel)
    {
    case PCA_CHANNEL_0:
        *ValueL = PCAx->CCAP0L;
        *ValueH = PCAx->CCAP0H;
        break;
    case PCA_CHANNEL_1:
        *ValueL = PCAx->CCAP1L;
        *ValueH = PCAx->CCAP1H;
        break;
    case PCA_CHANNEL_2:
        *ValueL = PCAx->CCAP2L;
        *ValueH = PCAx->CCAP2H;
        break;
    case PCA_CHANNEL_3:
        *ValueL = PCAx->CCAP3L;
        *ValueH = PCAx->CCAP3H;
        break;
    case PCA_CHANNEL_4:
        *ValueL = PCAx->CCAP4L;
        *ValueH = PCAx->CCAP4H;
        break;
    default:
        break;
    }
}

/**
  * @brief  Checks whether the specified PCA flag is set or not.
  * @param  PCAx: select the PCA peripheral.
  * @param  PCA_FLAG: specifies the flag to check.
  *          This parameter can be one of the following values:
  *            @arg PCA_FLAG_CC0: PCA Capture Compare 0 Flag
  *            @arg PCA_FLAG_CC1: PCA Capture Compare 1 Flag
  *            @arg PCA_FLAG_CC2: PCA Capture Compare 2 Flag
  *            @arg PCA_FLAG_CC3: PCA Capture Compare 3 Flag
  *            @arg PCA_FLAG_CC4: PCA Capture Compare 4 Flag
  *            @arg PCA_FLAG_OVERFLOW: PCA Capture Compare overflow Flag
  *
  * @retval The new state of PCA_FLAG (SET or RESET).
  */
FlagStatus PCA_GetFlagStatus(PCA_TypeDef* PCAx, uint16_t PCA_FLAG)
{
    ITStatus bitstatus = RESET;

    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));
    assert_param(IS_PCA_GET_FLAG(PCA_FLAG));

    if ((PCAx->CR & PCA_FLAG) != (uint16_t)RESET)
    {
        bitstatus = SET;
    }
    else
    {
        bitstatus = RESET;
    }

    return bitstatus;
}

/**
  * @brief  Clears the PCA's pending flags.
  * @param  PCAx: select the PCA peripheral.
  * @param  PCA_FLAG: specifies the flag bit to clear.
  *          This parameter can be any combination of the following values:
  *            @arg PCA_FLAG_CC0: PCA Capture Compare 0 Flag
  *            @arg PCA_FLAG_CC1: PCA Capture Compare 1 Flag
  *            @arg PCA_FLAG_CC2: PCA Capture Compare 2 Flag
  *            @arg PCA_FLAG_CC3: PCA Capture Compare 3 Flag
  *            @arg PCA_FLAG_CC4: PCA Capture Compare 4 Flag
  *            @arg PCA_FLAG_OVERFLOW: PCA Capture Compare overflow Flag
  *
  * @retval None
  */
void PCA_ClearFlag(PCA_TypeDef* PCAx, uint16_t PCA_FLAG)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));
    assert_param(IS_PCA_CLEAR_FLAG(PCA_FLAG));

    /* Clear the flags */
    PCAx->CR &= ~PCA_FLAG;
}

/**
  * @brief  Checks whether the PCA interrupt has occurred or not.
  * @param  PCAx: select the TIM peripheral.
  * @param  PCA_IT: specifies the TIM interrupt source to check.
  *          This parameter can be one of the following values:
  *            @arg PCA_IT_CC0: PCA Capture Compare 0 Interrupt source
  *            @arg PCA_IT_CC1: PCA Capture Compare 1 Interrupt source
  *            @arg PCA_IT_CC2: PCA Capture Compare 2 Interrupt source
  *            @arg PCA_IT_CC3: PCA Capture Compare 3 Interrupt source
  *            @arg PCA_IT_CC4: PCA Capture Compare 4 Interrupt source
  *            @arg PCA_IT_OVERFLOW: PCA Capture Compare overflow Interrupt source
  *
  *
  * @retval The new state of the PCA_IT(SET or RESET).
  */
ITStatus PCA_GetITStatus(PCA_TypeDef* PCAx, uint16_t PCA_IT)
{
    ITStatus bitstatus = RESET;
    uint16_t itstatus = 0x0, itenable = 0x0;

    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));
    assert_param(IS_PCA_GET_IT(PCA_IT));

    if(PCA_IT == PCA_IT_OVERFLOW)
    {
        itstatus = PCAx->MOD & PCA_MOD_CFIE;
    }
    else if(PCA_IT == PCA_IT_CC0)
    {
        itstatus = PCAx->CCAPM0 & PCA_CCAPMx_CCIE;
    }
    else if(PCA_IT == PCA_IT_CC1)
    {
        itstatus = PCAx->CCAPM1 & PCA_CCAPMx_CCIE;
    }
    else if(PCA_IT == PCA_IT_CC2)
    {
        itstatus = PCAx->CCAPM2 & PCA_CCAPMx_CCIE;
    }
    else if(PCA_IT == PCA_IT_CC3)
    {
        itstatus = PCAx->CCAPM3 & PCA_CCAPMx_CCIE;
    }
    else if(PCA_IT == PCA_IT_CC4)
    {
        itstatus = PCAx->CCAPM4 & PCA_CCAPMx_CCIE;
    }

    itenable = PCAx->CR & PCA_IT;
    if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET))
    {
        bitstatus = SET;
    }
    else
    {
        bitstatus = RESET;
    }
    return bitstatus;
}

/**
  * @brief  Clears the PCAx's interrupt pending bits.
  * @param  PCAx: select the PCA peripheral.
  * @param  PCA_IT: specifies the pending bit to clear.
  *          This parameter can be any combination of the following values:
  *            @arg PCA_IT_CC0: PCA Capture Compare 0 Interrupt source
  *            @arg PCA_IT_CC1: PCA Capture Compare 1 Interrupt source
  *            @arg PCA_IT_CC2: PCA Capture Compare 2 Interrupt source
  *            @arg PCA_IT_CC3: PCA Capture Compare 3 Interrupt source
  *            @arg PCA_IT_CC4: PCA Capture Compare 4 Interrupt source
  *            @arg PCA_IT_OVERFLOW: PCA Capture Compare overflow Interrupt source
  *
  * @retval None
  */
void PCA_ClearITPendingBit(PCA_TypeDef* PCAx, uint16_t PCA_IT)
{
    /* Check the parameters */
    assert_param(IS_PCA_ALL_PERIPH(PCAx));
    assert_param(IS_PCA_IT(PCA_IT));

    /* Clear the IT pending Bit */
    PCAx->CR &= ~PCA_IT;
}



/**
  * @}
  */ /* End of group PCA */

/**
  * @}
  */ /* group tc32l010_Driver */
